package org.secangkirkopipanas.gxtcore.server.util;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.GeneralSecurityException;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;

import org.apache.log4j.Logger;

public class PasswordUtil {

	private static Logger _logger = Logger.getLogger(PasswordUtil.class);
	private static final String ALGORITHM = "PBEWithMD5AndDES";
	private static PBEParameterSpec pbeParamSpec;
	private static SecretKey pbeKey;

	static {
		byte[] salt = { (byte) 0xc7, (byte) 0x73, (byte) 0x21, (byte) 0x8c,
				(byte) 0x7e, (byte) 0xc8, (byte) 0xee, (byte) 0x99 };
		pbeParamSpec = new PBEParameterSpec(salt, 20);

		PBEKeySpec pbeKeySpec = new PBEKeySpec(new char[] { 'd', '4', 'N', '4',
				'm', '0', 'N', '!' });
		try {
			SecretKeyFactory keyFac = SecretKeyFactory.getInstance(ALGORITHM);
			pbeKey = keyFac.generateSecret(pbeKeySpec);
		} catch (GeneralSecurityException e) {
			e.printStackTrace();
			_logger.error(e.getMessage());
		}
	}

	public static byte[] encrypt(byte[] clearText)
			throws GeneralSecurityException {
		// Create PBE Cipher
		Cipher pbeCipher = Cipher.getInstance(ALGORITHM);

		// Initialize PBE Cipher with key and parameters
		pbeCipher.init(Cipher.ENCRYPT_MODE, pbeKey, pbeParamSpec);

		// Encrypt the cleartext
		return pbeCipher.doFinal(clearText);
	}

	public static byte[] decrypt(byte[] clearText)
			throws GeneralSecurityException {
		// Create PBE Cipher
		Cipher pbeCipher = Cipher.getInstance(ALGORITHM);

		// Initialize PBE Cipher with key and parameters
		pbeCipher.init(Cipher.DECRYPT_MODE, pbeKey, pbeParamSpec);

		// Encrypt the cleartext
		return pbeCipher.doFinal(clearText);
	}

	public static void writeCryptedFile(OutputStream out, String text) {
		try {
			byte[] cipherText = encrypt(text.getBytes());
			out.write(cipherText);
		} catch (Exception e) {
			_logger.error(e.getMessage());
		}
	}

	public static String readCryptedFile(InputStream in) {
		String clearText = null;
		try {
			byte[] buf = new byte[255];
			ByteArrayOutputStream byteOut = new ByteArrayOutputStream(255);
			int len = in.read(buf);
			while (len > -1) {
				byteOut.write(buf, 0, len);
				len = in.read(buf);
			}

			byte[] cipherText = byteOut.toByteArray();
			byte[] resultText = decrypt(cipherText);
			clearText = new String(resultText);
		} catch (Exception e) {
			_logger.error(e.getMessage());
		}
		return clearText;
	}
}
